package cn.itsource.user.service.impl;

import cn.itsource.basic.constant.PetHomeConstans;
import cn.itsource.basic.constant.VerificationConstant;
import cn.itsource.basic.exception.CustomException;
import cn.itsource.basic.service.impl.BaseServiceImpl;
import cn.itsource.basic.util.AjaxResult;
import cn.itsource.basic.util.MD5Utils;
import cn.itsource.basic.util.StrUtils;
import cn.itsource.user.domain.LoginInfo;
import cn.itsource.user.domain.User;
import cn.itsource.user.domain.dto.LogininfoDto;
import cn.itsource.user.mapper.LoginInfoMapper;
import cn.itsource.user.mapper.UserMapper;
import cn.itsource.user.service.ILogininfoService;
import cn.itsource.user.service.IUserService;
import org.apache.commons.codec.digest.Md5Crypt;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class LogininfoServiceImpl extends BaseServiceImpl<LoginInfo> implements ILogininfoService {
    @Autowired
    private LoginInfoMapper mapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public AjaxResult login(LogininfoDto logininfoDto) throws CustomException {
        //校验规则
        CheckLoginData(logininfoDto);
        //根据username/phone/email 和type获取Logininfo
        LoginInfo loginInfo = mapper.getLoginInfo(logininfoDto.getUsername(),logininfoDto.getType());
       // System.out.println(loginInfo);
        //判断用户是否存在
        if (loginInfo==null){
            throw new CustomException("用户名不存在！");
        }
        //判断密码是否正确
        //System.out.println(loginInfo.getSalt());
        //System.out.println(MD5Utils.encrypByMd5(logininfoDto.getPassword()+loginInfo.getSalt()));
        if(!loginInfo.getPassword().equals(MD5Utils.encrypByMd5(logininfoDto.getPassword()+loginInfo.getSalt()))){
            throw new CustomException("密码错误!!");
        }
        //自定义一个jsessionid
        //获取一个随机数
        String token = UUID.randomUUID().toString();
        //System.out.println(token+"/....");
        //把登录信息存储到redis里面，并且有效期是30分钟，  key：token   value：登录用户对象
        redisTemplate.opsForValue().set(token, loginInfo, 30, TimeUnit.MINUTES);
        HashMap<Object, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("loginUser", loginInfo);
        return AjaxResult.me().setResultObj(map);
    }

    /**
     * 校验登录信息
     * @param logininfoDto
     */
    private void CheckLoginData(LogininfoDto logininfoDto) throws CustomException {
        if (StringUtils.isEmpty(logininfoDto.getUsername())){
            throw new CustomException("请输入用户名");
        }
       if (StringUtils.isEmpty(logininfoDto.getPassword())){
           throw new CustomException("请输入密码");
       }

    }

    @Override
    @Transactional
    public void register(LogininfoDto logininfoDto) throws CustomException {
        //校验规则
        checkData(logininfoDto);
        //创建logininfo
        LoginInfo loginInfo = createLogininfo(logininfoDto);
        //添加logininfo
        mapper.register(loginInfo);
        //创建User
        User user = createUser(loginInfo);
        //添加User
        userMapper.save(user);
    }

    /**
     * 校验手机号注册
     * @param logininfoDto
     * @throws CustomException
     */
    private void checkData(LogininfoDto logininfoDto) throws CustomException {
        //判断手机号是否为空
        if(StringUtils.isEmpty(logininfoDto.getPhone())){
            throw new CustomException("手机号不能为空");
        }
        //判断手机号是否注册
        User user = userMapper.selectByPhone(logininfoDto.getPhone());
        if(user!=null){
            throw new CustomException("该手机号已注册");
        }
        //判断验证码是否为空
        if (StringUtils.isEmpty(logininfoDto.getCode())){
            throw new CustomException("验证码不能为空");

        }
        String code = (String)redisTemplate.opsForValue().get(logininfoDto.getPhone()+":"+VerificationConstant.USER_REG);
        //判断验证码是否过期
        if (StringUtils.isEmpty(code)){
            throw new CustomException("验证码已过期");
        }
        //判断验证码是否正确
        if(!logininfoDto.getCode().equals(code.split(":")[0])){
            System.out.println(logininfoDto.getCode());
            System.out.println(code.split(":")[0]);
            throw new CustomException("验证码错误");
        }
        //判断密码是否为空
        if (StringUtils.isEmpty(logininfoDto.getPassword())){
            throw new CustomException("密码不能为空");
        }
        //判断确认密码是否为空
        if (StringUtils.isEmpty(logininfoDto.getConfigpassword())){
            throw new CustomException("确认密码不能为空");
        }
        //判断两次密码是否一致
        if(!logininfoDto.getPassword().equals(logininfoDto.getConfigpassword())){
            throw new CustomException("两次密码不一致");
        }
    }

    /**
     * 创建user
     * @param logininfo
     * @return
     */
    private User createUser(LoginInfo logininfo) {
        User user = new User();
        BeanUtils.copyProperties(logininfo, user);
        //设置状态
        user.setState(PetHomeConstans.OK);
        //设置Logininfo 也就是设置user表里的设置Logininfo_id
        user.setLogininfo(logininfo);
        return user;
    }

    /**
     * 创建Logininfo
     * @param logininfoDto
     * @return
     */
    private LoginInfo createLogininfo(LogininfoDto logininfoDto) {
        LoginInfo loginInfo = new LoginInfo();
        BeanUtils.copyProperties(logininfoDto, loginInfo);
        //随机获取10为盐值
        String random = StrUtils.getComplexRandomString(10);
        //设置盐值
        loginInfo.setSalt(random);
        //设置密码
        loginInfo.setPassword(MD5Utils.encrypByMd5(logininfoDto.getPassword()+random));
        //设置商家
        loginInfo.setType(logininfoDto.getType());
        return loginInfo;
    }
}
